//
//  AudioRecordHelper.m
//  BaiTengIM
//
//  Created by awh on 2019/7/1.
//  Copyright © 2019年 awh. All rights reserved.
//

#import "AudioRecordHelper.h"

#import <AVFoundation/AVFoundation.h>
#import "amrFileCodec.h"

#define kMaxRecordLength  30

@interface AudioRecordHelper()<AVAudioRecorderDelegate>

@property (nonatomic, strong) NSDate *startDate;
@property (nonatomic, strong) NSDate *endDate;

@property (nonatomic, strong) AVAudioRecorder *recorder;
@property (nonatomic, strong) NSDictionary *recordSetting;

@property(nonatomic, strong) NSTimer *recordTimer;
@property(nonatomic, assign) NSInteger recordSeconds;
@property (nonatomic, copy) void (^recordFinished)(NSString *path, NSInteger timeLength);

@end

@implementation AudioRecordHelper
SingleM(AudioRecordHelper);

#pragma mark - Public

- (void)startRecordWithPath:(NSString *)path
                 completion:(void(^)(NSError *error))completion {
    NSError *error = nil;
    do {
        if (self.recorder && self.recorder.isRecording) {
            error = [NSError errorWithDomain:@"正在进行录制" code:-1 userInfo:nil];
            break;
        }
        
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
        if (!error){
            [[AVAudioSession sharedInstance] setActive:YES error:&error];
        }
        
        if (error) {
            error = [NSError errorWithDomain:@"AVAudioSession SetCategory失败" code:-1 userInfo:nil];
            break;
        }
        
        NSString *wavPath = [[path stringByDeletingPathExtension] stringByAppendingPathExtension:@"wav"];
        NSURL *wavUrl = [[NSURL alloc] initFileURLWithPath:wavPath];
        self.recorder = [[AVAudioRecorder alloc] initWithURL:wavUrl settings:self.recordSetting error:&error];
        if(error || !self.recorder) {
            self.recorder = nil;
            error = [NSError errorWithDomain:@"文件格式转换失败" code:-1 userInfo:nil];
            break;
        }
        
        BOOL ret = [self.recorder prepareToRecord];
        if (ret) {
            self.startDate = [NSDate date];
            self.recorder.meteringEnabled = YES;
            self.recorder.delegate = self;
            ret = [self.recorder record];
            _recordSeconds = 0;
            [self.recordTimer fire];
        }
        
        if (!ret) {
            [self _stopRecord];
            [self.recordTimer invalidate];
            self.recordTimer = nil;
            self.recordSeconds = 0;
            error = [NSError errorWithDomain:@"准备录制工作失败" code:-1 userInfo:nil];
        }
        
    } while (0);
    
    if (completion) {
        completion(error);
    }
}

-(void)stopRecordWithCompletion:(void(^)(NSString *path, NSInteger timeLength))completion {
    self.recordFinished = completion;
    [self.recorder stop];
    [self.recordTimer invalidate];
    self.recordTimer = nil;
    self.recordSeconds = 0;
}

-(void)cancelRecord {
    [self _stopRecord];
    self.startDate = nil;
    self.endDate = nil;
}



- (instancetype)init {
    self = [super init];
    if (self) {
        _recordSetting = @{AVSampleRateKey:@(16000.0), AVFormatIDKey:@(kAudioFormatLinearPCM), AVLinearPCMBitDepthKey:@(16), AVNumberOfChannelsKey:@(1), AVEncoderAudioQualityKey:@(AVAudioQualityHigh)};
    }
    return self;
}


#pragma mark - Private

+ (int)wavPath:(NSString *)aWavPath toAmrPath:(NSString*)aAmrPath
{
    
    if (EM_EncodeWAVEFileToAMRFile([aWavPath cStringUsingEncoding:NSASCIIStringEncoding], [aAmrPath cStringUsingEncoding:NSASCIIStringEncoding], 1, 16))
        return 0;   // success
    
    return 1;   // failed
}

- (BOOL)_convertWAV:(NSString *)aWavPath toAMR:(NSString *)aAmrPath
{
    BOOL ret = NO;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:aAmrPath]) {
        ret = YES;
    } else if ([fileManager fileExistsAtPath:aWavPath]) {
        [AudioRecordHelper wavPath:aWavPath toAmrPath:aAmrPath];
        if ([fileManager fileExistsAtPath:aAmrPath]) {
            ret = YES;
        }
    }
    
    return ret;
}

#pragma mark - AVAudioRecorderDelegate

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
                           successfully:(BOOL)flag
{
    NSInteger timeLength = [[NSDate date] timeIntervalSinceDate:self.startDate];
    NSString *recordPath = [[self.recorder url] path];
    if (self.recordFinished) {
        if (!flag) {
            recordPath = nil;
        }
        // Convert wav to amr
        NSString *amrFilePath = [[recordPath stringByDeletingPathExtension] stringByAppendingPathExtension:@"amr"];
//        BOOL ret = [self _convertWAV:recordPath toAMR:amrFilePath];
//        if (ret) {
//            // Remove the wav
//            NSFileManager *fm = [NSFileManager defaultManager];
//            [fm removeItemAtPath:recordPath error:nil];
//
//            amrFilePath = amrFilePath;
//        } else {
//            recordPath = nil;
//            timeLength = 0;
//        }
        
        self.recordFinished(recordPath, timeLength);
    }
    self.recorder = nil;
    self.recordFinished = nil;
}

- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder
                                   error:(NSError *)error{
    AAIMLog(@"audioRecorderEncodeErrorDidOccur");
}

#pragma mark - Private

- (void)_stopRecord
{
    _recorder.delegate = nil;
    if (_recorder.recording) {
        [_recorder stop];
    }
    _recorder = nil;
    self.recordFinished = nil;
}


- (void)dealloc
{
    [self _stopRecord];
}

#pragma mark - getter

- (NSTimer *)recordTimer {
    if (!_recordTimer) {
        _recordTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(recordTimerAction:) userInfo:nil repeats:YES];
    }
    return _recordTimer;
}

- (void)recordTimerAction:(NSTimer *)timer {
    _recordSeconds ++;
    AAIMLog(@"录音时长=====%ld", _recordSeconds);
    if (_recordSeconds>20&&_recordSeconds<kMaxRecordLength) {
        if ([self.delegate respondsToSelector:@selector(audioCountdownWithTime:)]) {
            [self.delegate audioCountdownWithTime:kMaxRecordLength-_recordSeconds];
        }
    }
    if (_recordSeconds > kMaxRecordLength) {
        if (self.delegate && [self.delegate respondsToSelector:@selector(audioRecordHelperRecordTimeout)]) {
            [self.delegate audioRecordHelperRecordTimeout];
        }
    }
}


@end
